use std::ffi::{CStr, CString};
use std::os::raw::c_char;
mod jtool;
use jtool::jdate;
use jtool::jhttp;
use jtool::log;
use serde::{Deserialize, Serialize};
use serde_json::Result;

// region ---输出日志---begin---
#[no_mangle]
extern "C" fn debug(s: *mut c_char) {
    let slice = unsafe {
        assert!(!s.is_null());
        CStr::from_ptr(s)
    };
    let r_str = slice.to_str().unwrap();
    log::debug(r_str);
}

#[no_mangle]
extern "C" fn info(s: *mut c_char) {
    let slice = unsafe {
        assert!(!s.is_null());
        CStr::from_ptr(s)
    };
    let r_str = slice.to_str().unwrap();
    log::info(r_str);
}

#[no_mangle]
extern "C" fn error(s: *mut c_char) {
    let slice = unsafe {
        assert!(!s.is_null());
        CStr::from_ptr(s)
    };
    let r_str = slice.to_str().unwrap();
    log::error(r_str);
}

#[no_mangle]
extern "C" fn success(s: *mut c_char) {
    let slice = unsafe {
        assert!(!s.is_null());
        CStr::from_ptr(s)
    };
    let r_str = slice.to_str().unwrap();
    log::success(r_str);
}

#[no_mangle]
extern "C" fn exception(s: *mut c_char) {
    let slice = unsafe {
        assert!(!s.is_null());
        CStr::from_ptr(s)
    };
    let r_str = slice.to_str().unwrap();
    log::exception(r_str);
}

#[no_mangle]
extern "C" fn custom(folder: *mut c_char, s: *mut c_char) {
    let sliceFolder = unsafe {
        assert!(!folder.is_null());
        CStr::from_ptr(folder)
    };
    let folder_str = sliceFolder.to_str().unwrap();

    let slice = unsafe {
        assert!(!s.is_null());
        CStr::from_ptr(s)
    };
    let r_str = slice.to_str().unwrap();
    log::custom(folder_str, r_str);
}
// endregion ---输出日志---end---

#[no_mangle]
extern "C" fn test_receive_int(text: i32) {
    println!("Rust收到: {:?}", text);
}

#[no_mangle]
extern "C" fn test_return_int() -> i32 {
    return 999;
}

#[no_mangle]
extern "C" fn test_receive_string(text: *mut c_char) {
    let value = unsafe {
        assert!(!text.is_null());
        CStr::from_ptr(text)
    };
    let r_str = value.to_str().unwrap();
    println!("Rust收到: {:?}", r_str);
}

#[no_mangle]
extern "C" fn test_return_string() -> *mut c_char {
    let ping = String::from("rust返回".to_string() + &jdate::get_now_str());
    println!("Rust: {:?}", ping);
    let c_str_ping = CString::new(ping).unwrap();
    return c_str_ping.into_raw();
}

// #[no_mangle]
// unsafe extern "C" fn test_receive_struct(content: *const test_struct) {
//     let content = &*content;
//     println!("Rust收到-> userAge: {:?} userName {:?}", content.user_age,content.user_name);
// }

#[no_mangle]
extern "C" fn test_receive_struct(s: *mut c_char) {
    let slice = unsafe {
        assert!(!s.is_null());
        CStr::from_ptr(s)
    };
    let r_str = slice.to_str().unwrap();
    let t: test_struct = serde_json::from_str(r_str).unwrap();
    println!("Rust收到-> userAge: {:?} userName：{:?}", t.user_age,t.user_name);
    //log::debug(r_str);
    // let content = unsafe {
    //     assert!(!p_stu.is_null());
    //     println!("rust side print: {:?}", Box::from_raw(p_stu));
    //     Box::from_raw(p_stu)
    // };
    // println!(
    //     "Rust收到->{:?}",
    //     r_str
    // );
}

#[derive(Serialize, Deserialize)]
struct test_struct {
    user_age: i32,
    user_name: String,
}

// #[repr(C)]
// #[derive(Debug)]
// struct test_struct {
//     user_age: i32,
//     user_name: CString,
// }

#[no_mangle]
extern "C" fn test_return_struct() -> i32 {
    return 999;
}

#[no_mangle]
extern "C" fn test_receive_bytes(array: *mut [u8; 10]) {
    unsafe {
        let array2: [u8; 10] = *array;
        for value in array2.iter() {
            println!("value = {}", value);
        }
    }
}

#[no_mangle]
extern "C" fn get_html(url: *mut c_char) -> *mut c_char {
    let slice = unsafe {
        assert!(!url.is_null());
        CStr::from_ptr(url)
    };
    let r_url = slice.to_str().unwrap();

    let html = jhttp::request_url(r_url);
    let c_str_ping = CString::new(html).unwrap();
    return c_str_ping.into_raw();
}
